﻿using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace Socket_Push_SDK
{
    internal class LinkHub<T> : Hub where T : ILinkAction, new()
    {
        #region 构造函数
        /// <summary>
        /// key校验委托
        /// </summary>
        LinkCheck linkCheck { get; set; }
        /// <summary>
        /// 连接启动时委托
        /// </summary>
        LinkOnConnected linkOnConnected { get; set; }
        /// <summary>
        /// 连接断开时委托
        /// </summary>
        LinkOnDisconnected linkOnDisconnected { get; set; }
        /// <summary>
        /// 接收信息
        /// </summary>
        ReciveFunc reciveFunc { get; set; }
        /// <summary>
        /// 构造函数
        /// </summary>
        public LinkHub()
        {
            var creater = new T();
            linkCheck = creater.GetLinkCheck();
            linkOnConnected = creater.GetLinkOnConnected();
            linkOnDisconnected = creater.GetLinkOnDisconnected();
            reciveFunc = creater.GetReciveFunc();
        }
        #endregion

        /// <summary>
        /// 连接启动
        /// </summary>
        /// <returns></returns>
        public override async Task OnConnectedAsync()
        {
            await Task.Run(() =>
            {
                try
                {
                    var key = Context.GetQuery("key");
                    //判断key有效性
                    if (linkCheck(key, Context))
                    {
                        var Client = Clients.Client(Context.ConnectionId);
                        LinkPool.Add(Context.ConnectionId, key, Client, Context);
                        linkOnConnected?.Invoke(key, Context, Client);
                    }
                    else
                    {
                        Context.Abort();
                    }
                }
                catch
                {
                    Context.Abort();
                }

            });
        }

        /// <summary>
        /// 连接关闭
        /// </summary>
        /// <param name="exception"></param>
        /// <returns></returns>
        public override async Task OnDisconnectedAsync(Exception exception)
        {
            await Task.Run(() =>
            {
                LinkPool.RemovebyID(Context.ConnectionId);
                linkOnDisconnected?.Invoke(Context.GetQuery("key"), Context);
            });
        }

        /// <summary>
        /// 接收信息
        /// </summary>
        /// <param name="action"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public void Excute(string action, object data)
        {
            reciveFunc?.Invoke(Context.GetQuery("key"), action, data);
        }
    }
}
